package com.jh.paymentchannel.service;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URI;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.jh.paymentchannel.util.SignUtils;
import com.jh.paymentchannel.util.SwiftSignUtils;
import com.jh.paymentchannel.util.Util;
import com.jh.paymentchannel.util.XmlUtils;

import net.sf.json.JSONObject;

/**威富通反扫请求**/
@Service
public class SwiftB2CRequest  implements TopupRequest{

	private static final Logger log = LoggerFactory.getLogger(SwiftB2CRequest.class);
	
	@Value("${wft.req_url}")
	private String reqURL;
	
	@Value("${wft.mch_id}")
	private String mchID;
	
	@Value("${wft.key}")
	private String key;
	
	@Autowired
	Util util;
	
	@Override
	public Map<String, String> topupRequest(HttpServletRequest request,
			String amount, String ordercode, String orderdesc, String authcode,
			String notifyURL, String returnurl, String channelParam)
			throws UnsupportedEncodingException {
		log.info("进入反扫通道==========="+request+","+amount+","+ordercode+","+orderdesc+","+authcode+","+notifyURL+","+returnurl+","+channelParam+"============");
		 Map<String, String>  map = new HashMap<String, String>();
		 CloseableHttpClient httpClient = null;
		try {
			httpClient = HttpClients.createDefault();
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		HttpPost postMethod = new HttpPost(reqURL);
        List<BasicNameValuePair> nvps = new ArrayList<BasicNameValuePair>();
        nvps.add(new BasicNameValuePair("service", "unified.trade.micropay"));
        nvps.add(new BasicNameValuePair("mch_id", mchID));
        nvps.add(new BasicNameValuePair("out_trade_no", ordercode));
        nvps.add(new BasicNameValuePair("body", orderdesc));
        nvps.add(new BasicNameValuePair("total_fee", new BigDecimal(amount).multiply(new BigDecimal("100")).toString()));
        nvps.add(new BasicNameValuePair("mch_create_ip", request.getRemoteAddr()));
        nvps.add(new BasicNameValuePair("auth_code", authcode));//扫码支付授权码， 设备读取用户展示的条码或者二维码信息
        String nonce_str = String.valueOf(new Date().getTime());	
        nvps.add(new BasicNameValuePair("nonce_str", nonce_str));
        nvps.add(new BasicNameValuePair("attach",  ""));
        String timeStart = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        nvps.add(new BasicNameValuePair("time_start", timeStart));
        
        String res = null;
        try {
        String sign = 	SignUtils.signMD5Data(nvps, key);
		//nvps.add(new BasicNameValuePair("sign", ));
		
		SortedMap<String,String> paramsmap  =  new TreeMap<String,String>() ;
		
		paramsmap.put("mch_id", mchID);
		paramsmap.put("service", channelParam);
		paramsmap.put("out_trade_no", ordercode);
		paramsmap.put("body", orderdesc);
		paramsmap.put("attach",  "");
		paramsmap.put("total_fee", new BigDecimal(amount).multiply(new BigDecimal("100")).toString());
		paramsmap.put("mch_create_ip", request.getRemoteAddr());
		paramsmap.put("auth_code", authcode);
		paramsmap.put("time_start", timeStart);
		paramsmap.put("nonce_str", nonce_str);
		paramsmap.put("sign", sign);
		
		StringEntity entityParams = new StringEntity(XmlUtils.parseXML(paramsmap),"utf-8");
		log.info("XmlUtils.parseXML(paramsmap)=========="+XmlUtils.parseXML(paramsmap).toString());
		log.info("entityParams=========="+entityParams.toString());
        postMethod.setEntity(entityParams);
        log.info("postMethod=========="+postMethod.toString());
        CloseableHttpResponse response = httpClient.execute(postMethod);
        log.info("response=========="+response.toString());
            if(response != null && response.getEntity() != null){
                Map<String,String> resultMap = XmlUtils.toMap(EntityUtils.toByteArray(response.getEntity()), "UTF-8");
                res = XmlUtils.toXml(resultMap);
                log.info("resultMap=========="+resultMap.toString());
                if(resultMap.containsKey("sign")){
                    if(!SwiftSignUtils.checkParam(resultMap,key)){
                    	log.info("验证签名=========="+SwiftSignUtils.checkParam(resultMap,key));
                        res = "验证签名不通过";
                        map.put("resp_code", "failed");
                    }else{
                    	if(resultMap.containsKey("err_msg")) {
                    		String err_msg = resultMap.get("err_msg");
                    		if(err_msg.contains("密码")) {
                    			map.put("channel_type", "wftb2c");
                           	    map.put("resp_code", "paying");
                           	    return map;
                    		}
                    	}
                    	log.info("验证签名=========="+SwiftSignUtils.checkParam(resultMap,key));
                        if("0".equals(resultMap.get("status")) && "0".equals(resultMap.get("result_code"))){
                        	/**更新订单状态*/
        					/**调用下单，需要得到用户的订单信息*/
        					RestTemplate restTemplate=new RestTemplate();
        					
        					URI uri = util.getServiceUrl("transactionclear", "error url request!");
        					String url = uri.toString() + "/v1.0/transactionclear/payment/update";
        					
        					/**根据的用户手机号码查询用户的基本信息*/
        					MultiValueMap<String, String> requestEntity  = new LinkedMultiValueMap<String, String>();
        					requestEntity.add("status", "1");
        					requestEntity.add("order_code",  ordercode);
        					String result = restTemplate.postForObject(url, requestEntity, String.class);
        					
        					/**判断是否有外放的通道的处理， 如果有那么继续回调外放哦*/
        					uri = util.getServiceUrl("transactionclear", "error url request!");
        					url = uri.toString() + "/v1.0/transactionclear/payment/query/ordercode";
        					
        					
        					requestEntity  = new LinkedMultiValueMap<String, String>();
        					requestEntity.add("order_code",  ordercode);
        					result = restTemplate.postForObject(url, requestEntity, String.class);
        					
        					JSONObject jsonObject =  JSONObject.fromObject(result);
        					JSONObject resultObj  =  jsonObject.getJSONObject("result");
        					String outMerOrdercode  =  resultObj.getString("outMerOrdercode");
        					String phone            =  resultObj.getString("phone");
        					String  tranamount      =  resultObj.getString("amount");
        					String channelTag       =  resultObj.getString("channelTag");
        					if(outMerOrdercode != null && !outMerOrdercode.equalsIgnoreCase("")){
        						uri = util.getServiceUrl("channel", "error url request!");
        						url = uri.toString() + "/v1.0/channel/callback/yilian/notify_call";
        						requestEntity  = new LinkedMultiValueMap<String, String>();
        						requestEntity.add("merchant_no",  phone);
        						requestEntity.add("amount",  tranamount);
        						requestEntity.add("channel_tag",  channelTag);
        						requestEntity.add("order_desc",  URLEncoder.encode(orderdesc, "UTF-8"));
        						requestEntity.add("order_code",  outMerOrdercode);
        						requestEntity.add("sys_order",  ordercode);
        						requestEntity.add("notify_url", URLEncoder.encode(notifyURL, "UTF-8"));
        						result = restTemplate.postForObject(url, requestEntity, String.class);
        					}
                             map.put("channel_type", "wftb2c");
                             map.put("resp_code", "success");	
                             map.put("url", notifyURL);
                        }else{
                        	 map.put("channel_type", "wftb2c");
                        	 map.put("resp_code", "failed");
                        	 map.put("url", returnurl);
                        }
                    }
                } else {
                	 map.put("channel_type", "wftb2c");
                     map.put("resp_code", "failed");
                     map.put("url", returnurl);
                }
               
            }else{
                res = "操作失败";
                map.put("channel_type", "wftb2c");
                map.put("resp_code", "failed");
                map.put("url", returnurl);
            }
        } catch (Exception e) {
        	e.printStackTrace();
        	return null;
        }
        return map;
	}

}
